feat(core,isthmus): add DynamicParameter expression support#752
feat(core,isthmus): add DynamicParameter expression support#752bvolpato wants to merge 1 commit intosubstrait-io:mainfrom
Conversation
There was a problem hiding this comment.
These testcases feel a bit inconsistent. Sometimes they only assert the type, sometimes they only assert the parameter reference. Wouldn't it make sense to always check both?
|
Do you plan to also work on implementing the |
## Summary Add full support for `DynamicParameter` expressions and plan-level `DynamicParameterBinding`, enabling parameterized queries in substrait-go. This mirrors the functionality recently added in [substrait-java#752](substrait-io/substrait-java#752), ensuring Go consumers can create and read plans containing dynamic parameters. ## Changes ### Expression (`expr/expression.go`) - New `DynamicParameter` struct implementing the full `Expression` interface (`String`, `ToProto`, `Equals`, `Visit`, `IsScalar`, `GetType`, `ToProtoFuncArg`) - Proto deserialization in `ExprFromProto()` with nil safety check ### Builder (`expr/builder.go`) - `ExprBuilder.DynamicParam(outputType, paramRef)` method with `dynamicParamBuilder` - Implements `BuildExpr()` and `BuildFuncArg()` for use as function arguments ### Plan bindings (`plan/common.go`, `plan/plan.go`, `plan/builders.go`) - `DynamicParameterBinding` struct mapping parameter anchors to literal values - `Plan.ParameterBindings()` accessor - `FromProto()` / `ToProto()` serialization for parameter bindings - `Builder.PlanWithBindings()` method on the `Builder` interface ## Testing 17 new tests across two test files: - `expr/dynamic_parameter_test.go` — 11 tests covering basic construction, nullability, equality, visit, proto roundtrip (5 types), nil proto error, builder (3 cases), builder as function argument, and multiple parameters - `plan/dynamic_parameter_test.go` — 6 tests covering filter plan with bindings, project plan, multiple bindings, no bindings, JSON parsing roundtrip, and end-to-end builder usage All existing tests continue to pass with zero regressions.
2bf9bd6 to
a1807e4
Compare
Implement full support for Substrait DynamicParameter expressions, enabling parameterized placeholders in plan bodies instead of embedded literals. This maps bidirectionally to Calcite's RexDynamicParam (JDBC ? bind parameters). Changes: - Add Expression.DynamicParameter POJO with type and parameterReference - Wire visitor pattern across all expression visitors - Add proto conversion (POJO<->Proto) in both directions - Add Calcite conversion (RexDynamicParam<->DynamicParameter) - Replace UnsupportedOperationException in visitDynamicParam - Add debug stringification in ExpressionStringify - Add 20 tests covering proto roundtrips, Calcite conversions, and full end-to-end roundtrips
a1807e4 to
96bcc42
Compare
|
Thanks @nielspardon! Great question. I've rebased this PR on the latest Regarding I think it makes sense to handle
I'll open a follow-up issue to track |
Summary
Add full support for Substrait
DynamicParameterexpressions, enabling parameterized placeholders (analogous to JDBC?bind parameters) in plan bodies instead of embedded literals. This maps bidirectionally to Calcite'sRexDynamicParam.DynamicParameter enables plan reuse — the same plan structure can be compiled and cached once, then executed with different parameter values without re-planning. This is essential for prepared statement workflows and for exchanging plans between engines without leaking literal values.
Changes
Core POJO + Proto layer:
Expression.DynamicParameter— immutable POJO withtypeandparameterReferencefieldsExpressionVisitor/AbstractExpressionVisitor— newvisit(DynamicParameter)methodExpressionProtoConverter— POJO→Proto conversionProtoExpressionConverter— Proto→POJO conversion (DYNAMIC_PARAMETERcase)ExpressionCopyOnWriteVisitor— leaf-node handling (returnsOptional.empty())Calcite integration (isthmus):
RexExpressionConverter.visitDynamicParam()— replacesUnsupportedOperationExceptionwith actual Calcite→Substrait conversionExpressionRexConverter.visit(DynamicParameter)— Substrait→Calcite conversionDebug support:
ExpressionStringify— added DynamicParameter stringificationTesting
20 tests total, all passing:
DynamicParameterRoundtripTestin core) — POJO↔Proto↔POJO for I64, nullable STRING, FP64, I32, DATE, BOOLEAN, DECIMAL, TIMESTAMPDynamicParameterTest) — direct Calcite↔Substrait conversions and project roundtripsDynamicParameterRoundtripTestin isthmus) — filter/projection/multi-type POJO roundtrips, Calcite-originated RexDynamicParam roundtrips, and full Substrait→Calcite→Substrait bidirectional roundtripsAll existing tests in
coreandisthmuscontinue to pass with zero regressions. PMD and Spotless checks are clean.